package org.oschina.api.dongtan.dao;

import java.util.Iterator;
import java.util.List;
import org.oschina.Constants;
import org.oschina.api.BaseDAO;
import org.oschina.api.comment.dao.CommentDAO;
import org.oschina.api.dongtan.model.Dongtan;
import org.oschina.api.dongtan.vo.DongtanVo;
import org.oschina.api.user.user.vo.UserVo;
import org.oschina.helper.query.IQueryCacheCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class DongtanDAO extends BaseDAO {

	@Autowired
	private CommentDAO commentDAO;

	private final String findVo="SELECT dt.id,dt.comment_id,dt.type,dt.content,us.id as 'author.id',us.username as 'author.username',us.headphoto as 'author.headphoto',dt.views_count,dt.comment_count,dt.create_time FROM "+
		Constants.DB_DONGTAN+" dt,"+Constants.DB_USER+" us WHERE dt.author_id=us.id";

	
	private final String findVoByType=findVo+" AND dt.type=? ORDER BY dt.create_time LIMIT ?,?";
	/**
	 * 根据类型返回
	 * @param type
	 * @param first
	 * @param max
	 * @return
	 */
	public List<DongtanVo> findVoByType(int type,int first,int max)
	{
		return getQueryHelper().query(findVoByType, new Object[]{type,first,max}, DongtanVo.class);
	}
	/**
	 * 根据类型返回数量
	 * @param type
	 * @return
	 */
	public int getCountByType(int type)
	{
		return (int) getQueryHelper().queryDataSum(new String[]{"type=?"}, new Object[]{type}, DongtanVo.class);
	}
	
	private final String findVoById=findVo+" AND dt.id=?";
	/**
	 * 根据ID返回
	 * @param id
	 * @return
	 */
	public DongtanVo findVoById(int id)
	{
		DongtanVo dongtan=findByCache(id);
		
		if(dongtan!=null)
		{
			cacheData(dongtan);
			return dongtan;
		}
		
		return (DongtanVo)getQueryHelper().queryForObject(findVoById, new Object[]{id}, DongtanVo.class);
	}
	private DongtanVo findByCache(int id)
	{
		return (DongtanVo)getCacheHelper().hget(getIdKey(id), DongtanVo.class);
	}

	/**
	 * 根据发表时间和类型查询
	 * @param type
	 * @param first
	 * @param max
	 * @return
	 */
	public List<DongtanVo> findVoByTime(final int type,int first,int max)
	{
		List<DongtanVo> result=getQueryHelper().query_cache(Constants.CACHE_DONGTAN_LIST,Constants.MAX_CACHE_DONGTAN, first, max, DongtanVo.class, 
			new IQueryCacheCallback()
			{
				@Override
				public List get(int first, int max)
				{
					return _findVoByTimeAndType(type,first,max);
				}
			}
		);
		
		Iterator<DongtanVo> iterator=result.iterator();
		while(iterator.hasNext())
		{
			DongtanVo dongtan=iterator.next();
			if(dongtan==null || !dongtan.getType().equals(type))
				iterator.remove();
		}
		return result;
	}
	
	private final String findVoByTimeAndType=findVo+" AND dt.type=? ORDER BY dt.create_time DESC,dt.views_count DESC LIMIT ?,?";
	private List<DongtanVo> _findVoByTimeAndType(int type,int first,int max)
	{
		return getQueryHelper().query(findVoByTimeAndType, new Object[]{type,first,max}, DongtanVo.class);
	}
	
	private final String findVoByHot=findVo+" AND dt.type=? ORDER BY dt.comment_count DESC,dt.views_count DESC LIMIT ?,?";
	/**
	 * 查询热门
	 * @param first
	 * @param max
	 * @return
	 */
	public List<DongtanVo> findVoByHot(int type,int first,int max)
	{
		if(maxCacheCount(first, max, Constants.MAX_CACHE_DONGTAN))
			return getQueryHelper().query(findVoByHot, new Object[]{type,first,max}, DongtanVo.class);
		
		return getQueryHelper().query_cache(findVoByHot, new Object[]{type,first,max}, DongtanVo.class);
	}
	
	/**
	 * 创建
	 * @param dongtan
	 * @return
	 */
	public Dongtan create(Dongtan dongtan)
	{
		getQueryHelper().insert(new String[]{"id","comment_id","content","author_id","ip","type","views_count","comment_count","create_time"}, 
				new Object[]{dongtan.getId(),dongtan.getComment_id(),dongtan.getContent(),dongtan.getAuthor().getId(),dongtan.getIp(),dongtan.getType(),dongtan.getViews_count(),dongtan.getComment_count(),dongtan.getCreate_time()}, DongtanVo.class);
		
		UserVo author=new UserVo();
		author.setId(dongtan.getAuthor().getId());
		author.setUsername(dongtan.getAuthor().getUsername());
		author.setHeadphoto(dongtan.getAuthor().getHeadphoto());
		
		DongtanVo dongtanVo=new DongtanVo();
		dongtanVo.setAuthor(author);
		dongtanVo.setContent(dongtan.getContent());
		dongtanVo.setComment_count(dongtan.getComment_count());
		dongtanVo.setViews_count(dongtan.getViews_count());
		dongtanVo.setCreate_time(dongtan.getCreate_time());
		dongtanVo.setId(dongtan.getId());
		dongtanVo.setType(dongtan.getType());
		dongtanVo.setComment_id(dongtan.getComment_id());
		
		if(getCacheHelper().llen(Constants.CACHE_DONGTAN_LIST)>Constants.MAX_CACHE_DONGTAN)
		{
			DongtanVo temp=(DongtanVo)getCacheHelper().rpop(Constants.CACHE_DONGTAN_LIST, DongtanVo.class);
			getCacheHelper().hdel(Constants.CACHE_DONGTAN, temp.getId());
		}
		
		getCacheHelper().lpush(Constants.CACHE_DONGTAN_LIST, dongtanVo.getId(), Constants.TIMEOUT_DONGTAN);
		getCacheHelper().hset(getIdKey(dongtanVo.getId()), dongtanVo, DongtanVo.class, Constants.TIMEOUT_DONGTAN);
		return dongtan;
	}
	
	/**
	 * 编辑
	 * @param dongtan
	 * @return
	 */
	public int edit(Dongtan dongtan)
	{
		updateCache(dongtan.getId(),new String[]{"content"},new Object[]{dongtan.getContent()});
		return (int) getQueryHelper().update(new String[]{"content=?"}, new String[]{"id=?"}, new Object[]{dongtan.getContent(),dongtan.getId()}, DongtanVo.class);
	}
	
	/**
	 * 更新浏览数量
	 * @param id
	 * @param count
	 */
	public void updateViewsCount(int id,int count)
	{
		getCacheHelper().hincr(getIdKey(id), "views_count", count);
		batchUpdate_queue("UPDATE "+Constants.DB_DONGTAN+" SET views_count=views_count+? WHERE id=?", new Object[]{count,id});
	}
	
	/**
	 * 更新评论数量
	 * @param id
	 * @param count
	 */
	public void updateCommentCount(int id,int count)
	{
		getCacheHelper().hincr(getIdKey(id), "comment_count", count);
		batchUpdate_queue("UPDATE "+Constants.DB_DONGTAN+" SET comment_count=comment_count+? WHERE id=?", new Object[]{count,id});
	}
	
	/**
	 * 更新类型
	 * @param id
	 * @param type
	 * @return
	 */
	public int updateType(int id,int type)
	{
		updateCache(id,new String[]{"type"},new Object[]{type});
		return (int) getQueryHelper().update(new String[]{"type=?"}, new String[]{"id=?"}, new Object[]{type,id}, DongtanVo.class);
	}
	
	private String getIdKey(Object id)
	{
		return getKey(Constants.CACHE_DONGTAN,id);
	}
	
	private void updateCache(int id,String fields[],Object values[])
	{
		updateCache(Constants.CACHE_DONGTAN,Constants.TIMEOUT_DONGTAN,id,fields,values);
	}
	
	private boolean updateCache(String key,int timeout,int id,String fields[],Object values[])
	{
		return updateCache(key,id,fields,values,timeout);
	}
	
	private void cacheData(DongtanVo dongtanVo)
	{
		commentDAO.needCache(dongtanVo.getComment_id());
	}
}